package main

import "log"

func main() {
	// demo1()
	// demo2()
	// demo3()
	// demo4()
	// demo5()
	// demo6()
	demo7()
}

// var m map只是声明变量 ， 没有分配实际内存 ，所以下面赋值是报错的
func demo1() {
	var m map[string]string
	m["one"] = "one"
}

// append当原空间不足或者未分配，会指向新的内存空间
func demo2() {
	var s []string
	s = append(s, "123")
}

// 没有key 的话 ， 会返回类型零值出来， 这里使用ok语法来判断是否存在这个key
func demo3() {
	var m map[string]int = make(map[string]int)
	m["one"] = 1

	val, ok := m["key"]
	if ok {
		log.Println("存在，取出没有的key：key,val=", val)
	} else {
		log.Println("不存在，取出没有的key：key,val=", val)
	}

	// 2023/01/05 15:00:51 不存在，取出没有的key：key,val= 0
}

// 字符串不可以直接修改， 这里我们采用byte切片来进行修改
func demo4() {
	str := "world"
	// 编译器直接报错
	// str[0]=1
	strByte := []byte(str)
	// 这里我们必须是字节类型的
	strByte[0] = '1'
	str = string(strByte)
	log.Println("str=", str)
}

// 如何从panic中恢复
// recover 只能捕获到上一层的panic
func demo5() {

	defer func() {
		err := recover()
		log.Println(err)
	}()

	// 这个只能捕获到报错1 ， 但是捕获不到报错
	// defer func() {
	// 	defer func() {
	// 		err := recover()
	// 		log.Println(err)
	// 	}()
	// 	panic("报错1")
	// }()

	panic("报错")
}

// range 迭代 map是无序的
func demo6() {
	dic := make(map[string]string, 2)
	dic["one"] = "一"
	dic["two"] = "二"
	log.Println("dic len=", len(dic), "，地址：", &dic)
	dic["tree"] = "三"
	log.Println("dic len=", len(dic), "，地址：", &dic)

	for k, v := range dic {
		log.Println("dic 循环 ， key=", k, ",val=", v)
	}
}

// 这里因为defer 是在 函数退出前执行 如果放在for循环中去执行的话
// 可能会导致资源延迟释放
func demo7() {
	for i := 0; i < 10; i++ {
		defer func(j int) {
			log.Println(j)
		}(i)
	}

	log.Println("循环结束")
}
